package com.nfha.algorithm.taskassign;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Random;




public class GroupInfo {
	
	private final static double[] WTS=new double[] {0.4,0.2,0.2,0.2};


	public String id;

	public Employee[] employees;

	public int toDoTaskCount, doingTaskCount, doneTaskCount, totalTaskCount;

	public int priority1, priority2, priority3, priority4;

	public double wt, wtRate;

	public GroupInfo(String id, Employee[] employees) {
		super();
		this.id = id;
		this.employees = employees;

		int maxToDoTaskCount = 0, maxDoingTaskCount = 0, maxDoneTaskCount = 0, maxTotalTaskCount = 0;
		for (Employee employee : this.employees) {
			toDoTaskCount += employee.toDoTasks.size();
			doingTaskCount += employee.doingTasks.size();
			doneTaskCount += employee.doneTasks.size();
			totalTaskCount += employee.totalTaskCount();

			maxDoingTaskCount = maxDoingTaskCount > employee.doingTasks.size() ? maxDoingTaskCount
					: employee.doingTasks.size();
			maxDoneTaskCount = maxDoneTaskCount > employee.doneTasks.size() ? maxDoneTaskCount
					: employee.doneTasks.size();
			maxToDoTaskCount = maxToDoTaskCount > employee.toDoTasks.size() ? maxToDoTaskCount
					: employee.toDoTasks.size();

			maxTotalTaskCount = maxTotalTaskCount > employee.totalTaskCount() ? maxTotalTaskCount
					: employee.totalTaskCount();
		}

		totalTaskCount += maxTotalTaskCount;
		toDoTaskCount += maxToDoTaskCount;
		doneTaskCount += maxDoneTaskCount;
		doingTaskCount += maxDoingTaskCount;

	}

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return this.id;
	}

	/*
	 * 
	 * （1）  有无正在执行的任务：
组合内所有人员都无当前正在执行的任务，计10分；组合内有1人有当前正在执行的任务，计6分；组合内有2人有当前正在执行的任务，计3分；组合内有3人及以上有当前正在执行的任务，计0分；

	 * 
	 */
	public void updatePriority1() {
		int p = 10,count=0;
		for (Employee employee : this.employees) {
			if (employee.doingTasks.size() > 0) {
				count++;
				
			}
		}
		if(count==1) {
			p=6;
		}else if(count==2) {
			p=3;
		}else if(count>=3) {
			p=0;
		}
		
		priority1 = p;
	}

	
	
	/*
	 * 新的待派任务，与组内所有人员都是监管点一致（监管点为空的，视同一致）的，计10分；与组内1人监管点不一致，
	 * 其他人员监管点一致的，计6分；与组内2人监管点不一致，计3分；与组内3人及以上监管点不一致，计3分
	 */
	public void updatePriority2(String portCode) {
		int p = 10,count=0;
		
		for (Employee employee : this.employees) {
			
			String curPortCode=null;
			/*
			 * 人员当前监管点判断方法：系统根据人员当前执行的任务判断人员所处的监管点；
			 
			 * 
			 * 既无当前正在执行的任务、又无派单任务的，监管点为空。
			 */
			if(employee.doingTasks.size()>0) {
				// 有多条当前正在执行的任务时，选择最近一条开始执行的任务判定监管点；
				curPortCode=employee.doingTasks.get(0).portCode;
			}else if(employee.toDoTasks.size()>0) {
				//无当前正在执行的任务时，选择最近一条派单的任务判定监管点；
				curPortCode=employee.toDoTasks.get(0).portCode;
			}
			
			
			if (!portCode.equals(curPortCode) && curPortCode != null) {
				count++;
				
			}
		}

		if(count==1) {
			p=6;
		}else if(count==2) {
			p=3;
		}else if(count>=3) {
			p=0;
		}

		priority2 = p;
	}


	/*
	 * 对所有组合的待办任务数进行计算并排序，计算方法为组内所有人员待办任务数总和+组内待办任务数最多的人员的任务数；
	 * 按从少到多的排序赋值，待办工作量最少的计10分，待办工作量第二少的计9分，
	 */
	public static void updatePriority3(List<GroupInfo> groupInfos) {
		int P = 10;
		Collections.sort(groupInfos, new Comparator<GroupInfo>() {

			@Override
			public int compare(GroupInfo o1, GroupInfo o2) {
				// TODO Auto-generated method stub
				return o1.toDoTaskCount - o2.toDoTaskCount;
			}
		});
		for (int i = 0; i < groupInfos.size(); i++) {
			//if (this.id.equals(groupInfos.get(i).id)) {
				int p = P -i;

				for (int j = 1; j <= i; j++) {
					
					if (groupInfos.get(i).toDoTaskCount == groupInfos.get(i - j).toDoTaskCount) {
						p++;
					} else {
						break;
					}
				}
               groupInfos.get(i).priority3=p;
			//}
		}
		
	}

	/*
	 * 对所有组合的当天总任务数进行计算并排序，计算方法为组内所有人员总任务数总和+组内总任务数最多的人员的任务数；
	 * 按从少到多的排序赋值，总任务量最少的计10分，第二少的计9分，以此类推
	 */
	public static void updatePriority4(List<GroupInfo> groupInfos) {
		int P = 10;
		Collections.sort(groupInfos, new Comparator<GroupInfo>() {

			@Override
			public int compare(GroupInfo o1, GroupInfo o2) {
				// TODO Auto-generated method stub
				return o1.totalTaskCount - o2.totalTaskCount;
			}
		});
		for (int i = 0; i < groupInfos.size(); i++) {
			//if (this.id.equals(groupInfos.get(i).id)) {
				int p = P-i ;
				// 
				for (int j = 1; j <= i; j++) {
					if (groupInfos.get(i).totalTaskCount == groupInfos.get(i - j).totalTaskCount) {
						p++;
					} else {
						break;
					}
				}
				groupInfos.get(i).priority4 = p;
			//}
		}
		
	}

	// （4）优先选择当天总任务（待办、在办、已办）较少的组合。
	// （对所有组合的当天总任务数进行计算并排序，计算方法为组内所有人员总任务数总和+组内总任务数最多的人员的任务数；按从多到少赋予的排序值设定权重）
	public void updateWT(List<GroupInfo> groupInfos) {
		double p = this.priority1 *WTS[0] +
				this.priority2 *WTS[1] +
				this.priority3 *WTS[2] +
				this.priority4 *WTS[3];
		wt = p;
	}

	public void updateWTRate(List<GroupInfo> groupInfos) {
		double totalWt = 0;
		for (GroupInfo groupInfo : groupInfos) {
			totalWt += groupInfo.wt;
		}
		// System.out.println(totalWt);
		wtRate = this.wt / totalWt;
	}

	/*
	 * 1）当分值存在并列最高时，系统随机在并列组时选择其中一组作为最终派单组；
（2）当分值最高值不存在并列，且分数最高值比次高值高1分及以上的，选择分数最高值组为最终派单组；
（3）当分值最高值不存在并列，且分数最高值比次高值差在1分以内的，最高值和次高值按7：3的概率随机选出最终派单组；

	 */
	public static GroupInfo draw(Map<String, GroupInfo> groupInfoMap) {
		Random random=new Random();
		GroupInfo re = null,firstGroup=null;
	    List<GroupInfo> groupInfos=new ArrayList<>(groupInfoMap.values())
	    		,topGroupInfos=new ArrayList<>()
	    		,orderGroupInfos=new ArrayList<>()		
	    		;
		Collections.sort(groupInfos, new Comparator<GroupInfo>() {

			@Override
			public int compare(GroupInfo o1, GroupInfo o2) {
				// TODO Auto-generated method stub
				if(o1.wt==o2.wt)return 0;
				else if(o1.wt>o2.wt)return -1;
				return 1;
				
			}
		});
		firstGroup=groupInfos.get(0);
		topGroupInfos.add(firstGroup);
		orderGroupInfos.add(firstGroup);
		for(int i=1;i<groupInfos.size();i++) {
			GroupInfo iGroup=groupInfos.get(i);
			if(iGroup.wt==firstGroup.wt) {
				topGroupInfos.add(iGroup);
			}else {
				orderGroupInfos.add(iGroup);
				break;
			}
			
		}
		String msg="";
		if(topGroupInfos.size()>1) {
			
			int ri=random.nextInt(topGroupInfos.size());
			re=topGroupInfos.get(ri);
			msg="当分值"+re.wt+"存在并列最高"+topGroupInfos.size()+"个时，系统随机在并列组时选择其中一组作为最终派单组；";
		}else {
			GroupInfo group0=orderGroupInfos.get(0),group1=orderGroupInfos.get(1);
			if(group0.wt-group1.wt>1) {
				
				re=orderGroupInfos.get(0);
				msg="当分值最高值不存在并列，且分数最高值"+group0.wt+" 比次高值"+group1.wt+" 高1分及以上的，选择分数最高值组为最终派单组；";
			}else {
				
				int rn=random.nextInt(10);
				re=rn<7?orderGroupInfos.get(0):orderGroupInfos.get(1);
				msg="当分值最高值不存在并列，且分数最高值"+group0.wt+"比次高值"+group1.wt+"差在1分以内的，最高值和次高值按7：3的概率随机选出随机数"+rn+"最终派单组；";
			}
		}
        System.out.println("抽签结果:"+msg);
		return re;
	}
	
	
	public static void print(List<GroupInfo> groupInfos) {
		System.out.println("用户ID 	 	规则1  	规则2  	规则3  	规则4  	权重  	  概率 	  	规则3具体数据    规则4具体数据");
		for (GroupInfo groupInfo : groupInfos) {
			//groupInfoMap.put(groupInfo.id, groupInfo);
			String msg = MessageFormat.format("id:{0}  	 {1}  	 {2}  	 {3}  	 {4}    	{5}  	{6}    	 {7}   		{8}", groupInfo.id,
					groupInfo.priority1, groupInfo.priority2, groupInfo.priority3, groupInfo.priority4,
					groupInfo.wt, groupInfo.wtRate, groupInfo.toDoTaskCount, groupInfo.totalTaskCount);
			System.out.println(msg);
		}
	}


}
